package com.cloudbroker.bcs.platform.dav.middle.bizservice.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.apache.velocity.runtime.parser.node.MathUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.cloudbroker.bcs.common.entity.HSBCPSBackVO;
import com.cloudbroker.bcs.common.util.DateUtil;
import com.cloudbroker.bcs.common.util.StringUtil;
import com.cloudbroker.bcs.common.util.VOUtil;
import com.cloudbroker.bcs.platform.dav.bizapi.constants.HSBCPSErrorCodes.ClientErr;
import com.cloudbroker.bcs.platform.dav.bizapi.constants.HSBCPSErrorCodes.ExtendGroupErr;
import com.cloudbroker.bcs.platform.dav.bizapi.constants.PlugsCodes;
import com.cloudbroker.bcs.platform.dav.bizapi.constants.status.MustLoginStatus;
import com.cloudbroker.bcs.platform.dav.bizapi.constants.status.NeedLoginStatus;
import com.cloudbroker.bcs.platform.dav.bizapi.constants.type.PlugsContentSource;
import com.cloudbroker.bcs.platform.dav.bizapi.constants.type.TermType;
import com.cloudbroker.bcs.platform.dav.bizapi.service.base.vo.HSBCPSVO;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.plugs.ExtendAppGroupBizService;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.plugs.result.ExtendAppGroupDavListData;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.plugs.result.ExtendAppGroupDavListResult;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.plugs.result.ExtendAppGroupFansListData;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.plugs.result.ExtendAppGroupFansListResult;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.plugs.result.ExtendAppGroupWithExtendAppListData;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.plugs.result.ExtendAppWithPlugsResult;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.plugs.vo.ExtendAppGroupDelForm;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.plugs.vo.ExtendAppGroupForm;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.plugs.vo.ExtendAppGroupUpdateForm;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.plugs.vo.ExtendGroupBuildDefaultForm;
import com.cloudbroker.bcs.platform.dav.bizapi.service.business.plugs.vo.ExtendGroupListForm;
import com.cloudbroker.bcs.platform.dav.bizapi.t2service.business.ExtendGroupT2BizService;
import com.cloudbroker.bcs.platform.dav.common.util.SessionHelper;
import com.cloudbroker.bcs.platform.dav.middle.context.HSBCPSBizDataContext;
import com.cloudbroker.bcs.platform.dav.middle.entity.Broker;
import com.cloudbroker.bcs.platform.dav.middle.entity.ExtendApp;
import com.cloudbroker.bcs.platform.dav.middle.entity.ExtendAppGroup;
import com.cloudbroker.bcs.platform.dav.middle.entity.ExtendGroup;
import com.cloudbroker.bcs.platform.dav.middle.entity.Plugs;
import com.cloudbroker.bcs.platform.dav.middle.entity.PlugsType;
import com.cloudbroker.bcs.platform.dav.middle.service.BrokerService;
import com.cloudbroker.bcs.platform.dav.middle.service.ExtendAppGroupService;
import com.cloudbroker.bcs.platform.dav.middle.service.ExtendAppService;
import com.cloudbroker.bcs.platform.dav.middle.service.ExtendGroupService;
import com.cloudbroker.bcs.platform.dav.middle.service.PlugsService;
import com.cloudbroker.bcs.platform.dav.middle.service.PlugsTypeService;
import com.cloudbroker.bcs.platform.dav.middle.util.PlugsUtil;

@Service
@Scope("prototype")
public class ExtendAppGroupBizServiceImpl implements ExtendAppGroupBizService{

    private Logger logger = Logger.getLogger(this.getClass());
	@Resource
	private ExtendAppGroupService extendAppGroupService;
   
	@Resource
    private PlugsTypeService plugsTypeService;
	
	@Resource
	private PlugsService plugsService;
	
	@Resource
	private ExtendGroupService extendGroupService;

    @Resource
    private ExtendAppService extendAppService;

	@Resource
	private BrokerService brokerService;
	
	@Resource
	private ExtendGroupT2BizService extendGroupT2;
	
	public ExtendAppGroupDavListResult funcExtendAppByGroup(ExtendGroupListForm form){
		ExtendAppGroupDavListResult result = new ExtendAppGroupDavListResult();
		
		ExtendGroup extendGroup = new ExtendGroup();
		extendGroup.setExtend_group_id(Long.valueOf(form.getExtend_group_id()));
		extendGroup.setExtend_group_status(1);
		extendGroup.setTenant_id(HSBCPSBizDataContext.getTenantId());
		List<ExtendGroup> groupList = extendGroupService.query(extendGroup);
		if(groupList == null || groupList.size() == 0){
			return VOUtil.genErrorResult(ExtendGroupErr.EXTEND_GROUP_NOT_FUND, ExtendAppGroupDavListResult.class);
		}
		
		ExtendAppGroup g = new ExtendAppGroup();
		g.setExtend_group_id(Long.valueOf(form.getExtend_group_id()));
		g.setTenant_id(HSBCPSBizDataContext.getTenantId());
		List<ExtendAppGroupDavListData> list = extendAppGroupService.queryWithPlugsForDav(g);
		result.newDataList().addAll(list == null ? new ArrayList<ExtendAppGroupDavListData>() : list);
		
		return VOUtil.setSuccessResult(result);
	}

	public ExtendAppGroupFansListResult funcExtendAppByGroupFans(ExtendAppGroupForm form){
		ExtendAppGroupFansListResult result = new ExtendAppGroupFansListResult();

		ExtendGroup oneGroup = new ExtendGroup();
		oneGroup.setExtend_group_key(form.getExtend_group_key());
		List<ExtendGroup> groupList = extendGroupService.query(oneGroup);
		if(groupList != null && groupList.size() > 0){
		    oneGroup = groupList.get(0);
			
			ExtendAppGroup g = new ExtendAppGroup();
			g.setTenant_id(oneGroup.getTenant_id());
			g.setExtend_group_id(oneGroup.getExtend_group_id());
			
			List<ExtendAppGroupFansListData> list = extendAppGroupService.queryWithPlugsForFans(g);
			StringBuffer needLoginStr = new StringBuffer();
			for (ExtendAppGroupFansListData d : list) {
			    if("1".equals(d.getNeed_login())){
    			    needLoginStr.append(d.getCode());
    			    needLoginStr.append(",");
			    }
            }
			needLoginStr.setLength(needLoginStr.length() > 0 ? needLoginStr.length() - 1 : 0);
			SessionHelper.getInstance().clearNewNeedLoginExtendAppsByBrokerId(oneGroup.getBroker_id(), needLoginStr.toString());
			result.newDataList().addAll(list);
		}
		
		return VOUtil.setSuccessResult(result);
	}
	
    @Override
    public HSBCPSBackVO funcInitBrokerAppGroup(HSBCPSVO form) {
        int brokerCount = 0;
        int exceptionCount = 0;
        int programeExceptionCount = 0;
        try {
            logger.info("................清空数据.................");
            logger.info("清空plugs表");
            plugsService.deleteAll();

            logger.info("清空plugsType表");
            plugsTypeService.deleteAll();
            
            logger.info("清空extendApp表");
            extendAppService.deleteAll();
            
            logger.info("清空extendAppGroup表");
            extendAppGroupService.deleteAll();
            
            logger.info("清空extendGroup");
            extendGroupService.deleteAll();
            logger.info("................清空数据 完成.................");
            
            logger.info("................添加基础数据.................");
            logger.info("添加plugsType");
            PlugsType plugsType = PlugsUtil.getInstance().packPlugsType();
            plugsTypeService.save(plugsType);
            logger.info("添加plugsType完成");
            
            logger.info("添加plugs");
            List<Plugs> list = PlugsUtil.getInstance().packPlugsDb(plugsType.getPlugs_type_id());
            for (Iterator<Plugs> iterator = list.iterator(); iterator.hasNext();) {
                Plugs p = iterator.next();
                plugsService.save(p);
            }
            logger.info("添加plugs 完成");
            
            logger.info("....................应用与分组关系处理...................");
            int pageSize = 99;
            int pageNo = 1;
            int limitPageNo = 0;
            boolean isContinue = true;
            
            while(isContinue){
                limitPageNo = (pageNo - 1) * pageSize;
                List<Broker> brokerList = brokerService.getBrokerAccountList(null, null, null, limitPageNo, pageSize);
                if(brokerList == null || brokerList.isEmpty()) {
                    break;
                }
                brokerCount += brokerList.size();
                
                if(brokerList.size() < pageSize) {
                    isContinue = false;
                }
                
                logger.info("第" + (pageNo) + "次获取dav个数" + list.size());
                pageNo++;
                
                ExtendGroupBuildDefaultForm defaultGroupForm = new ExtendGroupBuildDefaultForm();
                for (Broker broker : brokerList) {
                    synchronized (this.getClass()) {
                        defaultGroupForm.setBroker_id(String.valueOf(broker.getBroker_id()));
                        HSBCPSBackVO backVo = extendGroupT2.funcExtendGroupBuildDefault(defaultGroupForm);
                        if(!"0".equals(backVo.getError_no())){
                        	programeExceptionCount++;
                        }
                    }
                }
            }
        } catch (Exception e) {
            exceptionCount++;
        }
        logger.info("....................应用与分组关系处理 完成...................");
        logger.info("..........共处理dav" + brokerCount + "个,异常" + exceptionCount + "个" +"程序调用异常" +programeExceptionCount);
        return VOUtil.genSuccessBackVo();
    }

    @Override
    public HSBCPSBackVO funcAddPlugsToBrokerAppGroup(HSBCPSVO form) {
        int brokerCount = 0;
        int extendappCount = 0;
        int exceptionCount = 0;
        try {
            logger.info("................基础数据.................");
            PlugsType plugsType = new PlugsType();
            plugsType.setName("全部");
            List<PlugsType> typeList = plugsTypeService.query(plugsType);

            logger.info("添加plugs");
            List<Plugs> list = PlugsUtil.getInstance().addPlugsDb(typeList.get(0).getPlugs_type_id());
            for (Iterator<Plugs> iterator = list.iterator(); iterator.hasNext();) {
                Plugs p = iterator.next();
                int count = 0;
                switch(p.getCode()){
                    /*                    case "trade":
                        Plugs tradePlugs = new Plugs();
                        tradePlugs.setName(PlugsCodes.trade.getName());
                        tradePlugs.setStatus(1);
                        tradePlugs.setCode(PlugsCodes.trade.getCode());
                        count = plugsService.count(tradePlugs);
                        break;
                    case "diagnoses":
                        Plugs diagnosesPlugs = new Plugs();
                        diagnosesPlugs.setName(PlugsCodes.diagnoses.getName());
                        diagnosesPlugs.setStatus(1);
                        diagnosesPlugs.setCode(PlugsCodes.diagnoses.getCode());
                        count = plugsService.count(diagnosesPlugs);
                        break;
                    case "updown":
                        Plugs updownPlugs = new Plugs();
                        updownPlugs.setName(PlugsCodes.updown.getName());
                        updownPlugs.setStatus(1);
                        updownPlugs.setCode(PlugsCodes.updown.getCode());
                        count = plugsService.count(updownPlugs);
                        break;
                    case "strategy":
                        Plugs strategyPlugs = new Plugs();
                        strategyPlugs.setName(PlugsCodes.strategy.getName());
                        strategyPlugs.setStatus(1);
                        strategyPlugs.setCode(PlugsCodes.strategy.getCode());
                        count = plugsService.count(strategyPlugs);
                        break;
                    case "outsider":
                        Plugs outsiderPlugs = new Plugs();
                        outsiderPlugs.setName(PlugsCodes.outsider.getName());
                        outsiderPlugs.setStatus(1);
                        outsiderPlugs.setCode(PlugsCodes.outsider.getCode());
                        count = plugsService.count(outsiderPlugs);
                        break;
                    case "tjxy":
                        Plugs tjxy = new Plugs();
                        tjxy.setName(PlugsCodes.tjxy.getName());
                        tjxy.setStatus(1);
                        tjxy.setCode(PlugsCodes.tjxy.getCode());
                        count = plugsService.count(tjxy);
                        break;*/
                    case "wonderful":
                        Plugs wonderful = new Plugs();
                        wonderful.setName(PlugsCodes.wonderful.getName());
                        wonderful.setStatus(1);
                        wonderful.setCode(PlugsCodes.wonderful.getCode());
                        count = plugsService.count(wonderful);
                        break;
                }
                
                if(MathUtils.isZero(count)) {
                    plugsService.save(p);
                }
            }
            logger.info("添加plugs 完成");

            logger.info("....................应用与分组关系处理...................");
            int pageSize = 100;
            int pageNo = 1;
            int limitPageNo = 0;
            boolean isContinue = true;

            Plugs plugs = new Plugs();
            plugs.setPlugs_type_id(typeList.get(0).getPlugs_type_id());
            list = plugsService.query(plugs);
            List<Plugs> plugsList = new ArrayList<>();
            for(Plugs p: list) {
                if(
/*                        PlugsCodes.trade.getCode().equals(p.getCode()) 
                        || PlugsCodes.diagnoses.getCode().equals(p.getCode()) 
                        || PlugsCodes.updown.getCode().equals(p.getCode()
                        || PlugsCodes.strategy.getCode().equals(p.getCode())
                        || PlugsCodes.outsider.getCode().equals(p.getCode())
                        || PlugsCodes.tjxy.getCode().equals(p.getCode())||*/
                         PlugsCodes.wonderful.getCode().equals(p.getCode())) {
                    plugsList.add(p);
                }
            }

            while(isContinue) {
                limitPageNo = (pageNo - 1) * pageSize;
                List<Broker> brokerList = brokerService.getBrokerAccountList(null, null, null, limitPageNo, pageSize);
                               
                if(brokerList == null || brokerList.isEmpty()) {
                    break;
                }
                brokerCount += brokerList.size();
                if(brokerList.size() < pageSize) {
                    isContinue = false;
                }

                logger.info("第" + (pageNo) + "次获取dav个数" + plugsList.size());
                pageNo++;

                ExtendApp app = null;
                for(Broker b: brokerList) {
                    synchronized (this.getClass()) {
                        Broker broker = brokerService.get(String.valueOf(b.getBroker_id()));
                        int count = 0;
                        for(Plugs p: plugsList) {
                            app = new ExtendApp();
                            app.setBroker_id(broker.getBroker_id());
                            app.setTenant_id(broker.getTenant_id());
                            Long sort = extendAppService.getMaxSort(app);
                            app.setPlugs_id(p.getPlugs_id());
                            count = extendAppService.count(app);
                            if(!MathUtils.isZero(count)){
                                count = 0;
                                extendappCount++;
                                continue;
                            }
                            app.setSort(sort);
                            app.setName(p.getName());
                            app.setCreater(p.getCreater());
                            app.setExtend_app_status(1);
                            app.setLink(p.getLink());
                            app.setCharge_mod(p.getCharge_mod());
                            app.setUsed(0);
                            app.setStart_time(new Date());
                            app.setValid_time(DateUtil.strToDate("2099-01-01", DateUtil.YYYY_MM_DD));
                            app.setCount(100000);
                            app.setTerm_type(TermType.FANS.getDbStr());
                            app.setPrice(p.getDiscount_price());
                            app.setMust_login(p.getMust_login());

                            extendAppService.save(app);
                            extendappCount++;
                        }

                        SessionHelper.getInstance().clearNewNeedLoginExtendAppsByBrokerId(HSBCPSBizDataContext.getBrokerId(), "");
                    }
                }
            }
        } catch (Exception e) {
            exceptionCount++;
        }
        logger.info("....................给每个dav添加两个新组件 完成...................");
        logger.info("..........共处理dav" + brokerCount + "个,购买应用" + extendappCount + "个,异常"+exceptionCount+"个..........");
        return VOUtil.genSuccessBackVo();
    }

    @Override
    public HSBCPSBackVO funcExtendAppGroupUpdate(ExtendAppGroupUpdateForm param) {
        ExtendAppGroup extendAppGroup = new ExtendAppGroup();
        extendAppGroup.setExtend_app_group_id(Long.valueOf(param.getExtend_app_group_id()));
        extendAppGroup.setTenant_id(HSBCPSBizDataContext.getTenantId());
        List<ExtendAppGroupWithExtendAppListData> list = extendAppGroupService.listWithExtendApp(extendAppGroup);
        if(list == null || list.size() == 0){
            return VOUtil.genErrorResult(ExtendGroupErr.EXTEND_APP_GROUP_NOT_EXIST, HSBCPSBackVO.class);
        }
        
        ExtendAppGroupWithExtendAppListData extendAppWithGroup = list.get(0);
        if(!StringUtil.isEmpty(param.getNeed_login())){
            if(NeedLoginStatus.NOLOGIN.getVal() == Integer.parseInt(param.getNeed_login())
                    && extendAppWithGroup.getMust_login() == MustLoginStatus.MUST.getVal()) {
                        return VOUtil.genErrorResult(ExtendGroupErr.NEED_LOGIN_CAN_NOT_UPDATE, HSBCPSBackVO.class);
            }
            extendAppGroup.setNeed_login(Integer.valueOf(param.getNeed_login()));
            SessionHelper.getInstance().clearNewNeedLoginExtendAppsByBrokerId(HSBCPSBizDataContext.getBrokerId(), "");
            extendAppGroupService.update(extendAppGroup);
            return VOUtil.genSuccessBackVo();
        }
        
        if(!StringUtil.isEmpty(param.getSort())){
            if(!judgePlugsSortRule(extendAppWithGroup, Integer.parseInt(param.getSort()),extendAppGroup)){
                return VOUtil.genErrorResult(ExtendGroupErr.EXTEND_APP_GROUP_SORT_RULE_ERR, HSBCPSBackVO.class);
            }
            return VOUtil.genSuccessBackVo();
        }
        return VOUtil.genErrorResult(ClientErr.NO_RECORD_UPDATED, HSBCPSBackVO.class);
    }
    
    /**
     * 
     * @param extendAppWithGroup extendappgroup表中信息
     * @param extendAppGroup 本次操作的排序值和主键id
     * @return
     */
    public boolean judgePlugsSortRule(ExtendAppGroupWithExtendAppListData extendAppWithGroup,int sort,ExtendAppGroup extendAppGroup){
        /**
         * 1.验证排序值是否正确
         * 2.可能存在多用户操作分组中应用 分组数据完整性验证
         * 3.交换位置
         * 4.检测第一个是否是外链
         */
        
        if(sort < -999999 || sort > 999999){
            return false;
        }
        
        ExtendAppGroup form = new ExtendAppGroup();
        form.setExtend_group_id(extendAppWithGroup.getExtend_group_id());
        form.setTenant_id(HSBCPSBizDataContext.getTenantId());
        List<ExtendAppGroupDavListData> groupAppList = extendAppGroupService.queryWithPlugsForDav(form);
        if(groupAppList == null || groupAppList.size() == 0){
            return false;
        }
        
        //查找当前对象
        int currentIndex = 0;
        for (int i = 0; i < groupAppList.size(); i++) {
            ExtendAppGroupDavListData groupApp = groupAppList.get(i);
            if(groupApp.getExtend_app_id().equals(extendAppWithGroup.getExtend_app_id())){
                currentIndex = i;
                break;
            }
        }
        
        //模拟交换位置
        int targetIndex = currentIndex + sort;
        ExtendAppGroupDavListData nextDavApp  = groupAppList.get(targetIndex);
        if(targetIndex < 0){return false;}
        Collections.swap(groupAppList, currentIndex, targetIndex);
        
        ExtendAppGroupDavListData firstApp = groupAppList.get(0);
        if(firstApp == null || PlugsContentSource.OUTSIDE.getVal().equals(firstApp.getContent_source())){return false;}
        
        //更新当前操作对象 
        extendAppGroup.setSort(extendAppWithGroup.getSort() + sort);
        extendAppGroupService.update(extendAppGroup);
        
        //更新受影响对象
        ExtendAppGroup nextBean = new ExtendAppGroup();
        nextBean.setTenant_id(HSBCPSBizDataContext.getTenantId());
        nextBean.setExtend_app_group_id(nextDavApp.getExtend_app_group_id());
        nextBean.setSort(nextDavApp.getSort() + (-sort));
        extendAppGroupService.update(nextBean);
        return true;
    }
    

    @Override
    public HSBCPSBackVO funcExtendAppGroupDel(ExtendAppGroupDelForm param) {
        ExtendAppGroup appGroup = extendAppGroupService.get(param.getExtend_app_group_id());
        if(appGroup == null){
            return VOUtil.genErrorResult(ExtendGroupErr.EXTEND_APP_GROUP_NOT_EXIST, HSBCPSBackVO.class);
        }
        
        //删除后执行重排序
        ExtendAppGroup form = new ExtendAppGroup();
        form.setExtend_group_id(appGroup.getExtend_group_id());
        form.setTenant_id(HSBCPSBizDataContext.getTenantId());
        List<ExtendAppGroup> groupAppList = extendAppGroupService.query(form);
        if(groupAppList != null && groupAppList.size() > 0){
            int i = 0;
            List<ExtendAppGroup> saveList = new ArrayList<ExtendAppGroup>();
            Iterator<ExtendAppGroup> iterator = groupAppList.iterator();
            while(iterator.hasNext()){
                ExtendAppGroup it = iterator.next();
                if(it.getExtend_app_group_id().equals(Long.valueOf(param.getExtend_app_group_id()))){continue;}
                it.setSort(Long.valueOf(i));
                saveList.add(it);
                i++;
            }
            
            if(saveList.size() == 0){
                extendAppGroupService.delByCondition(null, appGroup.getExtend_group_id().toString(), null, HSBCPSBizDataContext.getTenantId());
                return VOUtil.genSuccessBackVo();
            }
            
            ExtendAppGroup firstApp = saveList.get(0);
            ExtendAppWithPlugsResult firstAppProp = extendAppService.getAppPropById(firstApp);
            if(PlugsContentSource.OUTSIDE.getVal().equals(firstAppProp.getContent_source())){
                return VOUtil.genErrorResult(ExtendGroupErr.EXTEND_APP_GROUP_DEL_APP_RULE_ERR, HSBCPSBackVO.class);
            }
            
            extendAppGroupService.delByCondition(null, appGroup.getExtend_group_id().toString(), null, HSBCPSBizDataContext.getTenantId());
            for (ExtendAppGroup saveDb : saveList) {
                extendAppGroupService.save(saveDb);
            }
        }
        return VOUtil.genSuccessBackVo();
    }
}
